package org.third.integration.ldap;

import com.sun.jndi.ldap.LdapName;

import java.util.Hashtable;

import javax.naming.Context;
import javax.naming.NamingEnumeration;
import javax.naming.directory.SearchControls;
import javax.naming.directory.SearchResult;
import javax.naming.ldap.InitialLdapContext;

import org.junit.Test;
import org.third.common.utils.StreamUtils;
import org.third.integration.ldap.ldaps.LdapsSocketFactory;

public class LdapConnectionTest {
    public void testConnectionPool() throws Exception {
        final Hashtable<String, String> LDAP_SERVER_PROPS = new Hashtable<>();

        String url = new String("ldap://16.187.188.62:389");
        // String adminName ="CN=oyxiaoyuanxy,CN=Users,DC=Hebmc,DC=com";//AD的用户名
        String adminName = "cn=Manager,dc=hpeswlab,dc=net"; // 注意用户名的写法：domain\User 或 User@domain.com
        String adminPassword = "secret";
        // adminName = "adfshp\\zhang"; // 注意用户名的写法：domain\User 或 User@domain.com
        // adminPassword = "1Qazxsw2";

        LDAP_SERVER_PROPS.put(Context.SECURITY_AUTHENTICATION, "simple"); // LDAP访问安全级别
        LDAP_SERVER_PROPS.put(Context.SECURITY_PRINCIPAL, adminName); // AD User
        LDAP_SERVER_PROPS.put(Context.SECURITY_CREDENTIALS, adminPassword); // AD
        // Password
        LDAP_SERVER_PROPS.put(Context.INITIAL_CONTEXT_FACTORY, "com.sun.jndi.ldap.LdapCtxFactory"); // LDAP工厂类
        LDAP_SERVER_PROPS.put(Context.PROVIDER_URL, url);
        // LDAP_SERVER_PROPS.put(Context.DNS_URL, "dc//=com");

        // env.put(Context.SECURITY_PROTOCOL, "ssl");
        // //env.put("java.naming.referral", "follow");
        // String keystore = "c:/Java/jdk1.6.0_10/jre/lib/security/cacerts";
        // System.setProperty("javax.net.ssl.trustStore", keystore);
        //             hashtable.put("com.sun.jndi.ldap.connect.pool", "true");
        //             hashtable.put(Context.REFERRAL, "follow");

        LDAP_SERVER_PROPS.put("com.sun.jndi.ldap.connect.pool", "true");
        LDAP_SERVER_PROPS.put("com.sun.jndi.ldap.connect.pool.maxsize", "10");
        LDAP_SERVER_PROPS.put("com.sun.jndi.ldap.connect.pool.prefsize", "3");
        LDAP_SERVER_PROPS.put("com.sun.jndi.ldap.connect.pool.timeout", "3");
        LDAP_SERVER_PROPS.put("com.sun.jndi.ldap.connect.pool.initsize", "1");
        LDAP_SERVER_PROPS.put("com.sun.jndi.connect.pool.timeout", "30000");

    }

    @Test
    public void testConnectOpenLdap() throws Exception {
        Hashtable<String, Object> env = new Hashtable<>();

        String adminName = "";
        String adminPassword = "";
        env = new Hashtable<String, Object>();

        // String adminName = "CN=Administrator,CN=Users,DC=antipodes,DC=com";
        adminName = "cn=Manager,dc=hpeswlab,dc=com";
        adminPassword = "secret";
        env.put(Context.INITIAL_CONTEXT_FACTORY, "com.sun.jndi.ldap.LdapCtxFactory");

        // set security credentials, note using simple cleartext authentication
        env.put(Context.SECURITY_AUTHENTICATION, "simple");
        env.put(Context.SECURITY_PRINCIPAL, adminName);
        env.put(Context.SECURITY_CREDENTIALS, adminPassword);

        // connect to my domain controller
        env.put(Context.PROVIDER_URL, "ldap://16.187.188.62:389/dc=hpeswlab,dc=com");
        if (env.get(Context.PROVIDER_URL).toString().startsWith("ldaps://")) {
            // env.put("java.naming.ldap.factory.socket", LdapSslSocketFactory.class.getName());
            env.put("java.naming.ldap.factory.socket", LdapsSocketFactory.class.getName());
        }

        InitialLdapContext ctx = null;
        try {
            ctx = new InitialLdapContext(env, null);
            SearchControls cons = new SearchControls();
            cons.setSearchScope(SearchControls.SUBTREE_SCOPE);
            cons.setReturningAttributes(new String[] { "cn", "sn", "uid", "objectClass" });
            String filterExpr = "(&(cn={0})(objectClass=person))";
            Object[] filterArgs = new Object[] { "guser2000" };
            NamingEnumeration<SearchResult> searchResults = ctx.search("", filterExpr, filterArgs, cons);
            LdapUtil.printSearchResult(searchResults);
        } catch (Exception e) {
            // LdapUtilities.parseSubErrorCode(e.getMessage());
            e.printStackTrace();
        } finally {
            StreamUtils.closeQuietly(ctx);
        }

    }

    @Test
    public void testConnectOpenLdapAsAnonymous() throws Exception {
        Hashtable<String, Object> env = new Hashtable<>();

        String adminName = "";
        String adminPassword = "";
        env = new Hashtable<String, Object>();

        // String adminName = "CN=Administrator,CN=Users,DC=antipodes,DC=com";
        adminName = "cn=Manager,dc=hpeswlab,dc=com";
        adminPassword = "secret";
        env.put(Context.INITIAL_CONTEXT_FACTORY, "com.sun.jndi.ldap.LdapCtxFactory");

        // set security credentials, note using simple cleartext authentication
        env.put(Context.SECURITY_AUTHENTICATION, "simplde");
//        env.put(Context.SECURITY_PRINCIPAL, adminName);
//        env.put(Context.SECURITY_CREDENTIALS, adminPassword);

        // connect to my domain controller
        env.put(Context.PROVIDER_URL, "ldap://16.187.191.233:389/dc=my-domain,dc=com");
        if (env.get(Context.PROVIDER_URL).toString().startsWith("ldaps://")) {
            // env.put("java.naming.ldap.factory.socket", LdapSslSocketFactory.class.getName());
            env.put("java.naming.ldap.factory.socket", LdapsSocketFactory.class.getName());
        }

        InitialLdapContext ctx = null;
        try {
            ctx = new InitialLdapContext(env, null);
            SearchControls cons = new SearchControls();
            cons.setSearchScope(SearchControls.SUBTREE_SCOPE);
            cons.setReturningAttributes(new String[] { "cn", "sn", "uid", "objectClass" });
            String filterExpr = "(&(cn={0})(objectClass=top))";
            Object[] filterArgs = new Object[] { "test4" };
            NamingEnumeration<SearchResult> searchResults = ctx.search("", filterExpr, filterArgs, cons);
            LdapUtil.printSearchResult(searchResults);
        } catch (Exception e) {
            // LdapUtilities.parseSubErrorCode(e.getMessage());
            e.printStackTrace();
        } finally {
            StreamUtils.closeQuietly(ctx);
        }

    }

    public void testConnectActiveDirectory() throws Exception {
        Hashtable<String, Object> env = new Hashtable<>();
        env.put(Context.SECURITY_AUTHENTICATION, "simple");
        env.put(Context.PROVIDER_URL, "ldap://ldap.hp.com");
        InitialLdapContext ctx = null;
        try {
            ctx = new InitialLdapContext(env, null);
            SearchControls cons = new SearchControls();
            cons.setSearchScope(SearchControls.SUBTREE_SCOPE);
            cons.setReturningAttributes(new String[] { "cn", "sn" });
            String filterExpr = "";
            Object[] filterArgs = new Object[] {};
            NamingEnumeration<SearchResult> searchResults = ctx.search("uid=yong-jie.gong@hpe.com,ou=People,o=hp.com", filterExpr,
                    filterArgs, cons);
            LdapUtil.printSearchResult(searchResults);
        } catch (Exception e) {
            // LdapUtilities.parseSubErrorCode(e.getMessage());
            e.printStackTrace();
        } finally {
            StreamUtils.closeQuietly(ctx);
        }
    }

    @Test
    public void testLdapName() throws Exception {
        LdapName ldapName = new LdapName("cn=test1, dcx =sdf ");
        System.out.println(ldapName.toString());

    }

    @Test
    public void testConnectLdapAsSsl() throws Exception {
        Hashtable<String, Object> env = new Hashtable<>();

        String adminName = "", adminPassword = "", ldapUrl = "";
        env = new Hashtable<String, Object>();

        // String adminName = "CN=Administrator,CN=Users,DC=antipodes,DC=com";
        // adminName = "cn=Manager,dc=hpeswlab,dc=com";
        // adminPassword = "secret";
        ldapUrl = "ldaps://ldap.hp.com:636";
        String filterExpr = "uid=yong-jie.gong@hpe.com";
        String dnName = "ou=People,o=hp.com";

        adminName = "cn=Manager,dc=maxcrc,dc=com";
        adminPassword = "admin";
        ldapUrl = "ldaps://16.187.189.77:636";
        dnName="o=HPE,dc=maxcrc,dc=com";
        filterExpr="cn=testuser01";

        env.put(Context.INITIAL_CONTEXT_FACTORY, "com.sun.jndi.ldap.LdapCtxFactory");

        // set security credentials, note using simple cleartext authentication
        env.put(Context.SECURITY_AUTHENTICATION, "simple");
        env.put(Context.SECURITY_PRINCIPAL, adminName);
        env.put(Context.SECURITY_CREDENTIALS, adminPassword);
        env.put(Context.PROVIDER_URL, ldapUrl);
        // env.put("java.naming.ldap.factory.socket", LdapSslSocketFactory.class.getName());
        env.put("java.naming.ldap.factory.socket", LdapsSocketFactory.class.getName());
        if (ldapUrl.startsWith("ldaps://")) {
//            LdapsSocketFactory.setThreadLocalValidateCertificate(true);
        }

        InitialLdapContext ctx = new InitialLdapContext(env, null);
        SearchControls cons = new SearchControls();
        cons.setSearchScope(SearchControls.SUBTREE_SCOPE);
        cons.setReturningAttributes(new String[] { "cn", "sn", "uid" });

        Object[] filterArgs = new Object[] {};
        NamingEnumeration<SearchResult> searchResults = ctx.search(dnName, filterExpr, filterArgs, cons);
        LdapUtil.printSearchResult(searchResults);

        ctx.close();

    }

    public static void main(String[] args) {
        Boolean b1 = new Boolean(true);
        Boolean b2 = new Boolean(true);
        System.out.println(b1.logicalAnd(b2, b1));
    }

}
